package com.jse.service;

import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Paths;

import javax.annotation.Resource;
import javax.script.ScriptException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.jse.dao.Dao;
import com.jse.entity.Ioc;

import jdk.nashorn.api.scripting.NashornScriptEngine;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;

/**
 * NashornRun表达引擎执行类 mvc代理服务组件
 * 
 * @author dzh
 * 
 */
@Component
public class NashornService {

	Logger log = Logger.getLogger(NashornService.class);
	@Resource
	Dao dao;
	@Resource
	EhcacheService cache;
	@Resource
	NashornScriptEngine scriptEngine;
	@Autowired
	PropertiesProxy conf;
	@Resource
	Ioc ioc;

	public Object run(String jjs, String func, NutMap tbl,HttpServletRequest req,HttpServletResponse resp) {
		String jjs_path = this.getClass().getResource("/").getPath().substring(1);// .replace("/", "\\");
		boolean notExists = true;
		if (!Strings.isEmpty(jjs)) {
			String jjsaction = jjs + "\\" + func;
			if (Files.exists(Paths.get(jjs_path, jjsaction + ".jjs"), LinkOption.NOFOLLOW_LINKS)) {// 直接映射不存在
				jjs = jjsaction;
				notExists = false;
			} else if (func.contains("_")&&Files.exists(Paths.get(jjs_path, jjs+"\\"+func.substring(0, func.indexOf('_')) + ".jjs"), LinkOption.NOFOLLOW_LINKS)) {
				jjs = jjs + "\\" + func.substring(0, func.indexOf('_'));
				notExists = false;
			} else if (Files.exists(Paths.get(jjs_path, jjs + "/_.jjs"), LinkOption.NOFOLLOW_LINKS)) {
				jjs = jjs + "/_";
				notExists = false;
			}
		} else {
			jjs="index";
			if (Files.exists(Paths.get(jjs_path, func + ".jjs"), LinkOption.NOFOLLOW_LINKS)) {// 直接映射不存在
				notExists = false;
			}else if (Files.exists(Paths.get(jjs_path,"index.jjs"), LinkOption.NOFOLLOW_LINKS)) {// 直接映射不存在
				notExists = false;
			}
		}
		if (notExists) {
			log.warn(String.format("jjs: path %s/%s not jjs exists!", jjs,func));
			return null;
		}
		scriptEngine.put("req", req);
		scriptEngine.put("resp", resp);
		scriptEngine.put("session", req.getSession());
		scriptEngine.put("app", req.getServletContext());
		scriptEngine.put("conf", conf);
		scriptEngine.put("ioc", ioc);
		scriptEngine.put("dao", dao);
		scriptEngine.put("log", log);
		scriptEngine.put("cache", cache);
		scriptEngine.put("jjs", jjs_path);
		try {
			scriptEngine.eval(new InputStreamReader(this.getClass().getResourceAsStream("/jse.jjs")));
			scriptEngine.put("p", tbl);
			scriptEngine.eval(new String(Files.readAllBytes(Paths.get(jjs_path + jjs + ".jjs"))));
			if(Files.exists(Paths.get(jjs_path + "_.jjs"), LinkOption.NOFOLLOW_LINKS))
			scriptEngine.eval(new String(Files.readAllBytes(Paths.get(jjs_path  + "_.jjs"))));
			return scriptEngine.invokeFunction(func, tbl);
		} catch(Exception e) {
			log.warn(String.format("jjs ex:%s", e.getMessage()));
			return e;
		}
		
	}

	public Object run(String jjs, String func, Object tbl) throws ScriptException, NoSuchMethodException, IOException {
		String jjs_path = this.getClass().getResource("/").getPath().substring(1);// .replace("/", "\\");
		scriptEngine.put("conf", conf);
		scriptEngine.put("ioc", ioc);
		scriptEngine.put("dao", dao);
		scriptEngine.put("log", log);
		scriptEngine.put("cache", cache);
		scriptEngine.put("jjs", jjs_path);
		scriptEngine.put("p", tbl);
		scriptEngine.eval(new String(Files.readAllBytes(Paths.get(jjs_path + jjs + ".jjs"))));
		return scriptEngine.invokeFunction(func, tbl);
	}

	public static void main(String[] args) throws NoSuchMethodException, ScriptException, IOException {
		NashornService service = new NashornService();
		service.scriptEngine = (NashornScriptEngine) new NashornScriptEngineFactory().getScriptEngine();
		System.err.println(service.run("test", "test", "123"));
	}
}
